﻿using System;
using System.IO;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Avalonia.Styling;
using AvaloniaEdit;
using AvaloniaEdit.Document;
using AvaloniaEdit.Folding;
using AvaloniaEdit.TextMate;
using FluentAvalonia.UI.Controls;
using Markdown.Avalonia.Full;
using TextMateSharp.Grammars;

namespace DevHub.WindowsApp.Pages.Code;

public partial class MarkdownView : UserControl
{
    private RegistryOptions RegistryOptions { get; }
    private TextMate.Installation TextMateInstallation { get; }
    private FoldingManager FoldingManager { get; set; }
    private XmlFoldingStrategy FoldingStrategy { get; set; } = new();
    public MarkdownView()
    {
        InitializeComponent();
        Editor = this.FindControl<TextEditor>("Editor")!;
        ThemeBox = this.FindControl<FAComboBox>("ThemeBox")!;
        Markdown = this.FindControl<MarkdownScrollViewer>("Markdown");
        var theme = Application.Current!.ActualThemeVariant == ThemeVariant.Light ? ThemeName.Light : ThemeName.Dark;
        ThemeBox.ItemsSource =  Enum.GetValues<ThemeName>();
        ThemeBox.SelectedItem = theme;
        Editor.FontFamily = Avalonia.Media.FontFamily.Parse("Cascadia Code,Consolas,Menlo,Monospace");
        RegistryOptions = new RegistryOptions(theme);
        TextMateInstallation = Editor.InstallTextMate(RegistryOptions);
        Editor.Document = new TextDocument();
        TextMateInstallation.SetGrammar(RegistryOptions.GetScopeByExtension(".md"));
        Editor.TextChanged += EditorTextChange;
        FoldingManager = FoldingManager.Install(Editor.TextArea);
        FoldingStrategy.UpdateFoldings(FoldingManager, Editor.Document);
    }

    private void EditorTextChange(object? sender, EventArgs e)
    {
        FoldingStrategy.UpdateFoldings(FoldingManager, Editor.Document);
    }
    
    private void TextChanged(object? sender, EventArgs e)
    {
        Markdown.Markdown = Editor.Text;
    }

    private async void OpenFileClick(object? sender, RoutedEventArgs e)
    {
        var top = TopLevel.GetTopLevel(this);
        if (top == null) return;
        var resultList = await top.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions());
        if (resultList.Count == 0) return;
        var result = resultList[0];
        var reader = new StreamReader(await result.OpenReadAsync());
        Editor.Text = await reader.ReadToEndAsync();
        reader.Dispose();
    }

    private void ClearClick(object? sender, RoutedEventArgs e)
    {
        Editor.Text = "";
    }

    private void ThemeSelectionChanged(object? sender, SelectionChangedEventArgs e)
    {
        var selected = (ThemeName)ThemeBox.SelectedItem!;
        if (RegistryOptions == null!) return;
        TextMateInstallation.SetTheme(RegistryOptions.LoadTheme(selected));
    }
}